/**
 * @author temujin Feb 25, 2012
 */
package paim.wingchun.view.componentes;

import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.SwingConstants;

import paim.wingchun.app.Reflections;
import paim.wingchun.model.pojos.Erro;
import paim.wingchun.view.Dialogs;
import paim.wingchun.view.componentes.botoes.JButtonConstrutor;

/**
 * @author temujin Feb 25, 2012
 */
public abstract class AbstractComponent<T> extends JComponent implements SwingConstants,
        ConstantesComponent {

    private static final long serialVersionUID = 1L;

    JButton construtor;

    protected boolean hasConstrutor;

    private JLabel label;

    protected final int labelPosition;

    private JLabel warning;

    private Erro erro;

    protected Class<T> classe;

    protected AbstractComponent(Class<T> classe, boolean hasConstrutor, int labelPosition) {
        this.classe = classe;
        this.hasConstrutor = hasConstrutor;
        this.labelPosition = labelPosition;

        if ( classe != null ) {
            setLabel(Reflections.getRotuloS(classe));
            setName(classe.getSimpleName());
        }

        makeComponent();
    }

    protected abstract void makeComponent();

    public abstract AbstractComponent<T> setEditable(boolean b);

    public Class<T> getClasse() {
        return this.classe;
    }

    protected JButton getConstrutor() {
        if ( construtor == null ) {
            construtor = new JButtonConstrutor();
        }
        return construtor;
    }

    protected JLabel getLabel() {
        if ( label == null ) {
            label = new JLabel();
            label.setHorizontalAlignment(LEFT);
            label.setHorizontalTextPosition(LEFT);
            label.setFont(LABEL$Font);
            label.setForeground(LABEL$ForeColor);
            label.setBackground(LABEL$BackColor);
        }
        return label;
    }

    protected JLabel getWarning() {
        if ( warning == null ) {
            warning = new JLabel();
            warning.setHorizontalAlignment(CENTER);
            warning.setHorizontalTextPosition(CENTER);
            warning.addMouseListener(new MouseListener() {

                @Override
                public void mouseReleased(MouseEvent e) {}

                @Override
                public void mousePressed(MouseEvent e) {}

                @Override
                public void mouseExited(MouseEvent e) {}

                @Override
                public void mouseEntered(MouseEvent e) {}

                @Override
                public void mouseClicked(MouseEvent e) {
                    if ( getErro() == null )
                        return;

                    Dialogs.showInternalErro(AbstractComponent.this.getParent(), getErro());

                }
            });
        }
        return warning;
    }

    public void setLabel(String text) {
        getLabel().setText(text);
    }


    void cleanWarning() {
        getWarning().setText(null);
        /* para nao receber eventos do mouse */
        getWarning().setEnabled(false);
        getWarning().setToolTipText(null);
    }

    void setWarning(Color color) {
        getWarning().setText(WARNING_CHAR);
        getWarning().setForeground(color);
    }

    public Erro getErro() {
        return this.erro;
    }

    public void setErro(Erro erro) {
        this.erro = erro;

        switch ( erro.getLevel() ) {
            case AVISO:
                setWarning(Color.BLUE);
                break;
            case ALERTA:
                setWarning(Color.YELLOW);
                break;
            case ERRO:
            case ERRO$IMPEDITIVO:
            case ERRO$PRIORITARIO:
                setWarning(Color.RED);
                break;
            case NENHUM:
            default:
                cleanWarning();
                break;
        }
    }

    public void cleanErro() {
        this.erro = null;
        cleanWarning();
    }

    /**
     * @author temujin Feb 6, 2012 void
     */
    public void addActionListener(ActionListener l) {
        getConstrutor().addActionListener(l);
    }

    public abstract AbstractComponent<T> addConstrutor();

    /** @author temujin Mar 1, 2012 void */
    public AbstractComponent<T> removeConstrutor() {
        remove(getConstrutor());
        hasConstrutor = false;
        construtor = null;
        return this;
    }



    // enum WarningColor { Level.ALERTA
    // // Color.Red,
    // }

    //
    // public void addWarning();
    //
    // public void removeWarning();

}
